package com.cml.dm.admin.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cml.dm.admin.entity.DmExeLogger;
import com.cml.dm.admin.entity.DmMetadata;
import com.cml.dm.admin.mapper.DmExeLoggerMapper;
import com.cml.dm.admin.model.FileStoreModel;
import com.cml.dm.admin.service.QueryFactory;
import com.cml.dm.admin.service.SqlGenerateServiceFactory;
import com.cml.dm.admin.service.StoreFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class BackupAdapter {

    private static final Logger logger = LoggerFactory.getLogger(BackupAdapter.class);

    @Autowired
    private SqlGenerateServiceFactory sqlGenerateServiceFactory;

    @Autowired
    private QueryFactory queryFactory;

    @Autowired
    private StoreFactory storeFactory;

    @Autowired
    private DmExeLoggerMapper exeLoggerMapper;

    public void exec(DmMetadata dmMetadata, DmExeLogger dmExeLogger, Object extParameter){
        Map<String, JSONArray> dataMap = new HashMap<>();
        Map<String, List<String>> pkIdIndexsMap = new HashMap<>();
        DmMetadata metadata = dmMetadata;
        DmExeLogger exeLogger = dmExeLogger;
        do{
            try {
                exeLogger.setExeType(exeLogger.backup());
                List<String> sqls =sqlGenerateServiceFactory.getSqlGenerateService(metadata, exeLogger, extParameter).sqlGenerate(metadata, exeLogger, extParameter);
                /**
                 * 1、执行sql,  执行sql语句时，根据limit参数进行分页执行
                 * 2、形成json，并写入文件
                 * 3、更新logger
                 */
                JSONArray data = new JSONArray();
                List<String> pkIdIndexs = new ArrayList<>();
                for(String sql : sqls){
                    List<Map<String, Object>> maps = queryFactory.queryData(sql);
                    for (Map<String, Object> map : maps){
                        data.add(map);
                        pkIdIndexs.add(map.get(metadata.getPk()).toString());
                    }
                }
                dataMap.put(metadata.getNodeId(), data);
                pkIdIndexsMap.put(metadata.getNodeId(),pkIdIndexs);

                metadata = metadata.getNextDmMetadata();

            }catch (Exception e){
                logger.error("备份失败",e);
                throw new RuntimeException("备份失败");
            }
        }while (metadata != null) ;
        String path = this.store(dmMetadata,dmExeLogger, dataMap,pkIdIndexsMap);
        DmExeLogger updateBean = new DmExeLogger();
        updateBean.setBackupPath(path);
        updateBean.setId(dmExeLogger.getId());
        exeLoggerMapper.updateById(updateBean);
    }

    private String store(DmMetadata dmMetadata, DmExeLogger dmExeLogger, Map<String, JSONArray> dataMap,Map<String, List<String>> pkIdIndexsMap){
        FileStoreModel storeModel = new FileStoreModel();
        storeModel.setTaskId(dmMetadata.getTaskID());
        storeModel.setVersion(String.valueOf(dmMetadata.getVersion()));
        storeModel.setOrgId(dmExeLogger.getOrgId());
        storeModel.setDate(LocalDateTime.now());

        List<JSONObject> datas = new ArrayList<>();
        for(String nodeId : dataMap.keySet()){
            JSONObject dataItem = new JSONObject();
            List<String> pkIdIndexList = pkIdIndexsMap.get(nodeId);
            JSONObject nodeData = new JSONObject();
            nodeData.put("pkIdIndex",pkIdIndexList);
            nodeData.put("data",dataMap.get(nodeId));
            dataItem.put(nodeId, nodeData);
            datas.add(dataItem);
        }
        storeModel.setDatas(datas);
        return storeFactory.store(storeModel);
    }
}
